#ifndef __SIGNAL_HPP__
#define __SIGNAL_HPP__

#include <iostream>
#include <vector>
#include <functional>
#include <memory>
#include <algorithm>
#include <type_traits>

// 前向声明
template<typename Sender, typename... Args>
class Signal;

// 连接句柄类
template<typename Sender, typename... Args>
class Connection {
private:
    friend class Signal<Sender, Args...>;
    
    // 使用weak_ptr避免循环引用
    std::weak_ptr<std::function<void(Sender*, Args...)>> callback_;
    Signal<Sender, Args...>* signal_ = nullptr;
    
    Connection(const std::shared_ptr<std::function<void(Sender*, Args...)>>& callback, 
               Signal<Sender, Args...>* signal)
        : callback_(callback), signal_(signal) {}
    
public:
    Connection() = default;
    
    // 断开连接
    void disconnect();
    
    // 检查连接是否有效
    bool connected() const {
        return !callback_.expired();
    }
};

// 信号类 - 核心实现
template<typename Sender, typename... Args>
class Signal {
private:
    friend class Connection<Sender, Args...>;
    
    // 存储回调函数的共享指针
    std::vector<std::shared_ptr<std::function<void(Sender*, Args...)>>> callbacks_;
    
    // 发送者指针
    Sender* sender_;
    
    // 移除失效的回调
    void cleanup() {
        callbacks_.erase(
            std::remove_if(callbacks_.begin(), callbacks_.end(),
                [](const std::shared_ptr<std::function<void(Sender*, Args...)>>& ptr) {
                    return !ptr || ptr.use_count() == 1;
                }),
            callbacks_.end());
    }
    
public:
    // 构造函数，需要传入发送者指针
    explicit Signal(Sender* sender) : sender_(sender) {}
    
    // 禁止拷贝
    Signal(const Signal&) = delete;
    Signal& operator=(const Signal&) = delete;
    
    // 连接槽函数
    template<typename F>
    Connection<Sender, Args...> connect(F&& f) {
        auto callback = std::make_shared<std::function<void(Sender*, Args...)>>(std::forward<F>(f));
        callbacks_.push_back(callback);
        return Connection<Sender, Args...>(callback, this);
    }
    
    // 触发信号
    void emit(Args... args) {
        cleanup();
        for (auto& callback : callbacks_) {
            if (callback) {
                (*callback)(sender_, args...);
            }
        }
    }
    
    // 重载()操作符，方便触发
    void operator()(Args... args) {
        emit(args...);
    }
    
    // 获取连接数量
    size_t connection_count() const {
        return callbacks_.size();
    }
    
    // 获取发送者
    Sender* sender() const {
        return sender_;
    }
};

// Connection的disconnect实现
template<typename Sender, typename... Args>
void Connection<Sender, Args...>::disconnect() {
    if (auto callback = callback_.lock()) {
        if (signal_) {
            // 将回调设置为nullptr，Signal会在下次清理时移除
            *callback = nullptr;
            signal_->cleanup();
        }
        callback_.reset();
    }
}

// // 示例类
// class Button {
// private:
//     std::string name_;
    
// public:
//     // 点击信号
//     Signal<Button, int, int> clicked;
    
//     Button(const std::string& name) : name_(name), clicked(this) {}
    
//     void simulateClick(int x, int y) {
//         std::cout << "Button '" << name_ << "' clicked at (" << x << ", " << y << ")\n";
//         clicked(x, y);
//     }
    
//     const std::string& name() const {
//         return name_;
//     }
// };

// class TextBox {
// private:
//     std::string name_;
    
// public:
//     // 文本改变信号
//     Signal<TextBox, const std::string&> textChanged;
    
//     TextBox(const std::string& name) : name_(name), textChanged(this) {}
    
//     void setText(const std::string& text) {
//         std::cout << "TextBox '" << name_ << "' text changed to: " << text << "\n";
//         textChanged(text);
//     }
    
//     const std::string& name() const {
//         return name_;
//     }
// };

// // 示例使用
// int main() {
//     // 创建按钮和文本框
//     Button okButton("OK");
//     Button cancelButton("Cancel");
//     TextBox usernameBox("Username");
    
//     // 创建一个通用的槽函数，可以接收来自任何发送者的信号
//     auto universalSlot = [](auto* sender, auto&&... args) {
//         std::cout << "Universal slot: Received signal from ";
        
//         // 使用if constexpr和SFINAE检测sender类型
//         if constexpr (std::is_same_v<decltype(sender), Button*>) {
//             std::cout << "Button '" << sender->name() << "'";
//         } else if constexpr (std::is_same_v<decltype(sender), TextBox*>) {
//             std::cout << "TextBox '" << sender->name() << "'";
//         } else {
//             std::cout << "unknown sender type";
//         }
        
//         std::cout << " with args: ";
        
//         // 打印所有参数
//         ((std::cout << args << " "), ...);
//         std::cout << "\n";
//     };
    
//     // 连接通用槽函数到所有信号
//     auto conn1 = okButton.clicked.connect(universalSlot);
//     auto conn2 = cancelButton.clicked.connect(universalSlot);
//     auto conn3 = usernameBox.textChanged.connect(universalSlot);
    
//     // 创建特定类型的槽函数
//     auto buttonSlot = [](Button* btn, int x, int y) {
//         std::cout << "Button-specific slot: " << btn->name() 
//                   << " clicked at (" << x << ", " << y << ")\n";
//     };
    
//     auto textBoxSlot = [](TextBox* tb, const std::string& text) {
//         std::cout << "TextBox-specific slot: " << tb->name() 
//                   << " text changed to: " << text << "\n";
//     };
    
//     // 连接特定类型的槽函数
//     auto conn4 = okButton.clicked.connect(buttonSlot);
//     auto conn5 = usernameBox.textChanged.connect(textBoxSlot);
    
//     std::cout << "=== Simulating events ===\n";
    
//     // 模拟事件
//     okButton.simulateClick(100, 200);
//     cancelButton.simulateClick(150, 250);
//     usernameBox.setText("JohnDoe");
    
//     // 断开一个连接
//     std::cout << "\n=== Disconnecting universal slot from OK button ===\n";
//     conn1.disconnect();
    
//     // 再次触发事件
//     okButton.simulateClick(300, 400);
    
//     return 0;
// }

#endif // __SIGNAL_HPP__